Expand description

This library provides the core API that can be used to write smart contracts for the Concordium blockchain in the Rust programming language. It aims to provide safe wrappers around the core primitives exposed by the chain and accessible to smart contracts.

By default the library will be linked with the std crate, the rust standard library, however to minimize code size this library supports toggling compilation with the #![no_std] attribute via the feature std which is enabled by default.

To use this library without the std feature you have to disable it, which can be done, for example, as follows.

[dependencies.concordium-contracts-common]
default-features = false

In your project’s Cargo.toml file.

Wasm32

This crate supports both compilation to x86 native code, as well as to the wasm32-unknown-unknown target. When there is a conflict, the preference should always be to make the wasm32-unknown-unknown the more efficient one.

concordium-std

The functionality in this library is re-exported via the concordium-std crate, which is intended as the entry-point for development of smart contracts in Rust. concordium-std adds a number of helper macros and traits on top of the basic functionality available here.

Features

This library supports two features, std and derive-serde. The former one is enabled by default, but the latter is disabled.

The derive-serde feature is intended to be used by off-chain tools to make it easier to test smart contracts, as well as to inter-operate with them once they are deployed. It can also be used in unit tests, since enabling this feature exposes additional trait implementations on the defined types.

The reason these trait implementations are not enabled by default is that they have non-trivial dependencies, which tends to increase compilation times, as well as code size, if used accidentally.

Traits

The main traits defined in this crate deal with binary serialization. The general principles behind serialization is to consistently use little-endian encoding. The native endianess of Wasm32 (when, e.g., reading from linear memory) is little endian, thus having serialization in little endian means as little overhead as possible.

The two core traits are Serial and Deserial. The rest are helper traits there for convenience.

In particular, the Get is noteworthy. It makes it possible to omit writing the type explicitly, if it is already clear from the context, allowing us to write, e.g.,

   let n = source.get()?;

instead of

   let n = u8::deserial(source)?;

The Get trait has a generic implementation in terms of Deserial, so only the latter should be implemented for new types.

Modules

Currently defined attributes possible in a policy.

Types related to contract schemas. These are optional annotations in modules that allow the users of smart contracts to interact with them in a way that is better than constructing raw bytes as parameters.

Structs

Address of an account, as raw bytes.

The type of amounts on the chain

Tag of an attribute. See the module attributes for the currently supported attributes.

An attribute value. The meaning of the bytes is dependent on the type of the attribute.

Chain metadata accessible to both receive and init methods.

Address of a contract.

A contract name. Expected format: “init_<contract_name>”.

Add offset tracking inside a data structure.

Duration of time in milliseconds.

An entrypoint name (borrowed version). Expected format: “<func_name>” where the name of the function consists solely of ASCII alphanumeric or punctuation characters.

A contract name (owned version). Expected format: “init_<contract_name>”.

An entrypoint name (owned version). Expected format: “<func_name>”. Most methods on this type are available via the as_entrypoint_name and the methods on the EntrypointName type.

Parameter to the init function or entrypoint. Owned version.

A receive name (owned version). Expected format: “<contract_name>.<func_name>”. Most methods are available only on the ReceiveName type, the intention is to access those via the as_receive_name method.

Parameter to the init function or entrypoint.

Zero-sized type to represent an error when reading bytes and deserializing.

Policy on the credential of the account.

A receive name. Expected format: “<contract_name>.<func_name>”.

Timestamp represented as milliseconds since unix epoch.

Enums

Either an address of an account, or contract.

An error indicating why parsing of an amount failed. Since amount parsing is typically a user-facing activity this is fairly precise, so we can notify the user why we failed, and what they can do to fix it.

Errors that can occur when constructing a new AttributeValue.

This is essentially equivalent to the SeekFrom type from the rust standard library, but reproduced here to avoid dependency on std::io, as well as to use 32-bit integers to specify positions. This saves some computation and space, and is adequate for the kind of data sizes that are possible in smart contracts.

Constants

Size of an account address when serialized in binary. NB: This is different from the Base58 representation.

Traits

The Deserial trait provides a means of reading structures from byte-sources (Read).

The DeserialCtx trait provides a means of reading structures from byte-sources (Read) using contextual information. The contextual information is:

A more convenient wrapper around Deserial that makes it easier to write deserialization code. It has a blanked implementation for any read and serialize pair. The key idea is that the type to deserialize is inferred from the context, enabling one to write, for example,

The HasSize trait provides a function for getting the current byte size.

The Read trait provides a means of reading from byte streams.

The Seek trait provides a cursor which can be moved within a stream of bytes. This is essentially a copy of std::io::Seek, but avoiding its dependency on std::io::Error, and the associated code size increase. Additionally, the positions are expressed in terms of 32-bit integers since this is adequate for the sizes of data in smart contracts.

The Serial trait provides a means of writing structures into byte-sinks (Write).

The SerialCtx trait provides a means of writing structures into byte-sinks (Write) using contextual information. The contextual information is:

The Serialize trait provides a means of writing structures into byte-sinks (Write) or reading structures from byte sources (Read).

The Write trait provides functionality for writing to byte streams.

Functions

Read a HashMap as a list of key-value pairs given some length.

Read a HashSet as a list of keys, given some length. NB: This ensures there are no duplicates.

Read a BTreeMap as a list of key-value pairs given some length. NB: This ensures there are no duplicates, hence the specialized type. Moreover this will only succeed if keys are listed in order.

Read a BTreeMap as a list of key-value pairs given some length. Slightly faster version of deserial_map_no_length as it is skipping the order checking

Read a BTreeSet as a list of keys, given some length. NB: This ensures there are no duplicates, hence the specialized type. Moreover this will only succeed if keys are listed in order.

Read a BTreeSet as an list of key-value pairs given some length. Slightly faster version of deserial_set_no_length as it is skipping the order checking. The only check that is made to the set is that there are no duplicates.

Read a vector given a length.

Dual to to_bytes.

Check whether the given string is a valid contract entrypoint name. This is the case if and only if

Write a HashMap as a list of key-value pairs in to particular order, without the length information.

Write a HashSet as a list of keys in no particular order, without the length information.

Write a Map as a list of key-value pairs ordered by the key, without the length information.

Write a BTreeSet as an ascending list of keys, without the length information.

Write a slice of elements, without including length information. This is intended to be used either when the length is statically known, or when the length is serialized independently as part of a bigger structure.

Serialize the given value to a freshly allocated vector of bytes using the provided Serial instance.

Type Definitions

Contract address index. A contract address consists of an index and a subindex. This type is for the index.

Contract address subindex. A contract address consists of an index and a subindex. This type is for the subindex.

Reexport of the HashMap from hashbrown with the default hasher set to the fnv hash function.

Reexport of the HashSet from hashbrown with the default hasher set to the fnv hash function.

Index of the identity provider on the chain. An identity provider with the given index will not be replaced, so this is a stable identifier.

A policy with a vector of attributes, fully allocated and owned. This is in contrast to a policy which is lazily read from a read source. The latter is useful for efficiency, this type is more useful for testing since the values are easier to construct.

A type alias used to indicate that the value is a result of parsing from binary via the Serial instance.

Time at the beginning of the current slot, in miliseconds since unix epoch.

Derive Macros

Derive the Deserial trait. See the documentation of derive(Serial) for details and limitations.

Derive the Serial trait for the type.

A helper macro to derive both the Serial and Deserial traits. [derive(Serialize)] is equivalent to [derive(Serial, Deserial)], see documentation of the latter two for details and options: derive(Serial), derive(Deserial).